<?php
/**
 * 远程文件上传组件
 *
 * @author liang<lang@vip.deyi.com>
 * @since   2015/6/24 18:34
 * @copyright  deyi.com
 */

namespace Deyi\Functions;

use OSS\OssClient;
use Phalcon\Di;
use Qiniu\Auth;
use Qiniu\Storage\BucketManager;
use Qiniu\Storage\UploadManager;

/**
 * Class RemoteFileFunction
 * @package Deyi\Functions
 */
class RemoteFileFunction
{

    /**
     *  上传单个文件到FastDFS
     *
     * @author liang<lang@vip.deyi.com>
     * @param $file
     * @return bool|string
     * @throws \Exception
     */
    public static function uploadSingleFile($file)
    {
        $config = Di::getDefault()->get('config');
        if (isset($config->storage)) {
            switch ($config->storage->type) {
                case 'oss':
                    return self::uploadFileToAliyunOSS($file);
                    break;
                case 'qiniu':
                    return self::uploadFileToQiniu($file, self::getFullRemoteFilePath($file));
                    break;
            }
        }

        return self::uploadFileToFastDFS($file);
    }

    /**
     * 删除fastdfs上指定的文件
     *
     * @author liang<lang@vip.deyi.com>
     * @param $file
     * @return bool
     */
    public static function deleteFile($file)
    {
        $config = Di::getDefault()->get('config');
        if (isset($config->storage)) {
            switch ($config->storage->type) {
                case 'oss':
                    return self::deleteFileFromAliyunOSS($file);
                    break;
                case 'qiniu':
                    return self::deleteFileFromQiniu($file);
                    break;
            }
        }

        if (preg_match('/(group[0-9]+)\/(.*)/i', $file, $m)) {
            return fastdfs_storage_delete_file($m[1], $m[2]);
        }

        return false;
    }

    /**
     * 获取fastdfs指定文件数据值
     *
     * @author liang<lang@vip.deyi.com>
     * @param $file
     * @return bool
     */
    public static function getFileData($file)
    {
        if (preg_match('/(group[0-9]+)\/(.*)/i', $file, $m)) {
            return fastdfs_storage_download_file_to_buff($m[1], $m[2]);
        }

        return false;
    }

    public static function uploadFileToQiniu($filePath, $toFileName)
    {
        if (!file_exists($filePath)) {
            return false;
        }

        $config = Di::getDefault()->get('config');
        $auth = new Auth($config->qiniu->accesskey, $config->qiniu->secretkey);
        $token = $auth->uploadToken($config->qiniu->bucket);
        $uploadMgr = new UploadManager();
        list($ret, $err) = $uploadMgr->putFile($token, $toFileName, $filePath);
        if ($err !== null) {
            return false;
        }
        return $ret['key'];
    }

    public static function getFileListFromQiniu($prefix = '', $marker = '', $limit = 10)
    {
        $config = Di::getDefault()->get('config');
        $auth = new Auth($config->qiniu->accesskey, $config->qiniu->secretkey);
        $bucketMgr = new BucketManager($auth);
        list($iterms, $marker, $err) = $bucketMgr->listFiles($config->qiniu->bucket, $prefix, $marker, $limit);

        if ($err !== null) {
            return '';
        }

        return $iterms;
    }

    /**
     * 删除指定七牛文件
     *
     * @author liang<lang@vip.deyi.com>
     * @param $file
     * @return bool
     */
    public static function deleteFileFromQiniu($file)
    {
        $config = Di::getDefault()->get('config');
        $auth = new Auth($config->qiniu->accesskey, $config->qiniu->secretkey);
        $bucketMgr = new BucketManager($auth);
        $err = $bucketMgr->delete($config->qiniu->bucket, $file);
        if ($err !== null) {
            return false;
        }
        return true;
    }

    public static function uploadFileToFastDFS($filePath)
    {
        if (!file_exists($filePath)) {
            return false;
        }
        $result = fastdfs_storage_upload_by_filename($filePath);

        if (!$result) {
            throw new \Exception(fastdfs_get_last_error_info());
        }

        return $result['group_name'] . '/' . $result['filename'];
    }

    /**
     * 上传指定图片到阿里云OSS
     * @author lang@vip.deyi.com
     * @param $filePath
     * @param string $manualPath
     * @return bool|string
     */
    public static function uploadFileToAliyunOSS($filePath, $manualPath = '')
    {
        if (!file_exists($filePath) && !preg_match('/^https?:\/\//', $filePath)) {
            return false;
        }

        $getFile = @file_get_contents($filePath);
        if (!$getFile) {
            return false;
        }

        $config = Di::getDefault()->get('config');
        $ossClient = new OssClient($config->aliyun->accesskeyid, $config->aliyun->accesskeysecret, $config->aliyun->ossendpoint);
        $ossClient->setTimeout(60);
        $ossClient->setConnectTimeout(60);
        $res = $ossClient->putObject(
            $config->aliyun->ossbucket,
            $manualPath ? $manualPath : self::getFullRemoteFilePath($filePath),
            $getFile
        );

        if (isset($res['info']['url'])) {
            $tmp = parse_url($res['info']['url']);

            return ltrim($tmp['path'], '/');
        }

        return false;
    }

    /**
     * 上传base64 图片到阿里云
     * @param $file
     * @param string $manualPath
     * @return bool|string
     */

    public static function uploadBase64FileToAliyunOSS($file, $manualPath='')
    {
        if (!$file) {
            return false;
        }

        $config = Di::getDefault()->get('config');
        $ossClient = new OssClient($config->aliyun->accesskeyid, $config->aliyun->accesskeysecret, $config->aliyun->ossendpoint);
        $ossClient->setTimeout(60);
        $ossClient->setConnectTimeout(60);
        $res = $ossClient->putObject(
            $config->aliyun->ossbucket,
            self::getFullRemoteFilePath($manualPath),
            $file
        );

        if (isset($res['info']['url'])) {

            return $res['info']['url'];

        }

        return false;
    }


    public static function deleteFileFromAliyunOSS($filePath)
    {
        $config = Di::getDefault()->get('config');
        $ossClient = new OssClient($config->aliyun->accesskeyid, $config->aliyun->accesskeysecret, $config->aliyun->ossendpoint);

        return $ossClient->deleteObject($config->aliyun->ossbucket, ltrim($filePath, '/'));
    }


    /**
     * 生成远端文件访问路径
     * @author lang@vip.deyi.com
     * @param $filePath
     * @return string
     */
    public static function getFullRemoteFilePath($filePath)
    {
        if (is_file($filePath)) {
            return strtolower(date('Ymd/H/') . md5_file($filePath) . uniqid() . strrchr($filePath, '.'));
        }

        return strtolower(date('Ymd/H/') . md5(UtilFunction::getRandomString(64)) . uniqid() . $filePath);
    }

    /**
     * 罗列出指定endpoint指定目录下的文件信息
     * @version APP 6.3.5
     * @author lang@vip.deyi.com
     * @param $accessKeyId
     * @param $accessKeySecret
     * @param $ossEndpoint
     * @param $bucket
     * @param $path
     * @param $size
     * @return array
     */
    public static function listFilesFromAliyunOSS($accessKeyId, $accessKeySecret, $ossEndpoint, $bucket, $path, $size = 500)
    {
        $ossClient = new OssClient($accessKeyId, $accessKeySecret, $ossEndpoint);

        $list = [];
        $nextMarker = '';
        $cnt = 0;
        // 做一个最大限制
        while ($cnt <= 500) {
            try {
                $res = $ossClient->listObjects($bucket, [
                    'max-keys' => 500,
                    'prefix' => $path,
                    'delimiter' => '/',
                    'marker' => $nextMarker
                ]);

                $tmp = $res->getObjectList();

                foreach ($tmp as $v) {
                    $list[] = $v->getKey();
                }

                if (count($list) >= $size) {
                    return array_slice($list, 0, $size);
                }

                $nextMarker = $res->getNextMarker();
                if ($nextMarker === '') {
                    break;
                }
            } catch (\Exception $e) {
                return $list;
            }
            $cnt++;
        }

        return $list;
    }

    /**
     * 采集指定url图片数据
     * @version APP 6.3.7
     * @author lang@vip.deyi.com
     * @param $url
     * @return array|bool
     */
    public static function uploadImgFromUrl($url)
    {
        $res = HttpFunction::downTempFileToCacheFolder($url);

        if (!$res) {
            return false;
        }

        $path = ROOT_PATH . '/data/cache/' . $res;

        $imgSize = getimagesize($path);
        $fileSize = filesize($path);
        $width = 0;
        $height = 0;
        if ($imgSize) {
            $width = $imgSize[0];
            $height = $imgSize[1];
        }
        $fileType = UtilFunction::getImageTypeInfo($path);
        if ($ossPath = RemoteFileFunction::uploadFileToAliyunOSS($path)) {
            @unlink($path);
            return [
                'path' => $ossPath,
                'size' => $fileSize,
                'width' => $width,
                'height' => $height,
                'filetype' => $fileType
            ];
        }
        return false;
    }
}
